from typing import Optional

import requests

from dytoken import DyToken
from keycloak import Keycloak
from tools.utils import print_error, print_success

_base_api = "https://dayu-data-manager.changdu.vip"
_base_web = "https://dayu.changdu.vip"


class Dayu(object):
    _accesstoken = ""

    @staticmethod
    def _get_headers():
        headers = {
            "accept": "application/json, text/plain, */*",
            "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
            "accesstoken": Dayu._accesstoken,
            "content-type": "application/json",
            "origin": "https://dayu.changdu.vip",
            "referer": "https://dayu.changdu.vip/",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
        }
        return headers

    @staticmethod
    async def get_user_work_hours(deptId, userName: str, quarter: str = ""):
        """个人工时"""
        headers = Dayu._get_headers()
        json_data = {
            "deptId": deptId,
            "dateType": 2,
            "userName": userName,
            "quarter": quarter,
            "pageType": "person",
            "metricId": "1763541952052043778",
            "templateType": 2,
        }
        response = requests.post(
            f"{_base_api}/api/okrPage/drillDownCalculate",
            headers=headers,
            json=json_data,
        )

        if response.status_code == 200:
            return response.json()
        print(response.text)
        return None

    @staticmethod
    async def get_user_project_hours(deptId, startTime, endTime, pageIndex, pageSize):
        """项目填报公示"""
        headers = Dayu._get_headers()
        json_data = {
            "deptId": deptId,
            "projectId": [],
            "type": "team",
            "startTime": startTime,
            "endTime": endTime,
            "pageNum": pageIndex,
            "pageSize": pageSize,
        }

        response = requests.post(
            f"{_base_api}/api/teamPage/fetchUserListByWorkHours",
            headers=headers,
            json=json_data,
        )
        if response.status_code == 200:
            return response.json()
        print(response.text)
        return None

    @staticmethod
    async def get_user_metric(deptId, metricId, startTime, endTime):
        """用户指标"""
        headers = Dayu._get_headers()
        json_data = {
            "deptId": deptId,
            "metricId": metricId,
            "projectId": [],
            "type": "team",
            "startTime": startTime,
            "endTime": endTime,
            "pageSize": 9999,
        }

        response = requests.post(
            f"{_base_api}/api/teamPage/fetchMetricListByPage",
            headers=headers,
            json=json_data,
        )
        if response.status_code == 200:
            return response.json()
        print(response.text)
        return None

    @staticmethod
    async def drillDownMapList(
        deptId,
        userName,
        quarter,
        startTime,
        endTime,
        drillDownType,
    ) -> Optional[dict]:
        """用户指标"""
        headers = Dayu._get_headers()
        json_data = {
            "deptId": deptId,
            "userName": userName,
            "quarter": quarter,
            "dateType": 2,
            "startTime": startTime,
            "endTime": endTime,
            "pageNum": 1,
            "pageSize": 10,
            "pageType": None,
            "metricId": "1763541952052043778",
            "drillDownType": drillDownType,
            "templateType": 2,
        }

        response = requests.post(
            f"{_base_api}/api/okrPage/drillDownMapList",
            headers=headers,
            json=json_data,
        )
        if response.status_code == 200:
            return response.json()
        print(response.text)
        return None

    @staticmethod
    async def auth_code(
        session: requests.Session,
        sessionState: str,
        secretKey: str,
    ) -> Optional[dict]:
        """授权码登录"""
        headers = {
            "accept": "application/json, text/plain, */*",
            "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
            "Referer": _base_web + "/",
            "Content-Type": "application/json",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0",  # noqa: E501
        }

        data = {
            "sessionState": sessionState,
            "secretKey": secretKey,
            "redirectUri": f"{_base_web}/login",
        }
        url = f"{_base_api}/api/auth/code"
        response = session.post(
            url,
            headers=headers,
            json=data,
            verify=False,
        )

        if response.status_code == 200:
            result = response.json()
            return result

        return None

    @staticmethod
    async def login(username: str, password: str):
        """登录返回token"""

        # 获取缓存
        token = DyToken()
        accessToken = token.get()
        if accessToken:
            print("token ok")
            Dayu._accesstoken = accessToken["accessToken"]
            return

        # 重新登录
        with requests.Session() as session:
            params = Keycloak.authenticate(session, username, password)
            if params is None:
                print_success("Keycloak.authenticate faild!")
                return ""

        secretKey = params["code"]
        session_state = params["session_state"]
        accessToken = await Dayu.auth_code(session, session_state, secretKey)
        if accessToken is None:
            print("login exception,response none!")
            return

        if accessToken["code"] != 200:
            print_error(f"login faild! msg:{accessToken["msg"]}")
            return ""

        print_success("login succeeded.")
        Dayu._accesstoken = accessToken["data"]["accessToken"]
        token.set(accessToken["data"])
